/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package it.polimi.wcalendar.business.security.boundary;

import it.polimi.wcalendar.business.security.entity.District;
import it.polimi.wcalendar.business.security.entity.Event;
import it.polimi.wcalendar.business.security.entity.Notification;
import it.polimi.wcalendar.business.security.entity.PeopleInvited;
import it.polimi.wcalendar.business.security.entity.PeopleInvitedPK;
import it.polimi.wcalendar.business.security.entity.User;
import java.security.Principal;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.primefaces.model.ScheduleEvent;

/**
 * Gestisce le tabelle relative al calendario/eventi sul DB.
 *
 * @author unil
 */
@Stateless
public class CalendarDataManager {

    @PersistenceContext
    EntityManager em;

    public List getAllEventsByCreator(User creator) {
        return em.createNamedQuery("Event.findByCreator")
                .setParameter("creator", creator)
                .getResultList();
    }

    public List getAllEventsAttendTo(User user) {
        String query = "SELECT e FROM Event e, PeopleInvited p WHERE e.ide = p.peopleInvitedPK.ide AND p.peopleInvitedPK.idusr = :user AND p.answer = :answer";
        return em.createQuery(query)
                .setParameter("user", user.getNickname())
                .setParameter("answer", "yes")
                .getResultList();
    }

    public List getExistingOverlapEvents(User creator, Date startDate, Date endDate) {
        String query = "SELECT e FROM Event e, PeopleInvited p WHERE ((e.ide = p.peopleInvitedPK.ide AND p.peopleInvitedPK.idusr = :creator AND p.answer = :answer) OR (e.creator = :creator)) AND ((e.date < :start AND e.data_end > :start) OR (e.date < :end AND e.data_end > :end) OR (e.date > :start AND e.data_end < :end))";
        return em.createQuery(query)
                .setParameter("creator", creator.getNickname())
                .setParameter("answer", "yes")
                .setParameter("start", startDate)
                .setParameter("end", endDate)
                .getResultList();
    }

    public void saveEvent(Event event) {
        em.persist(event);
    }

    public Event loadEvent(Integer id) {
        return em.find(Event.class, id);
    }

    public void deleteEvent(Integer id) {
        em.remove(loadEvent(id));
    }

    public void updateEvent(Integer eventId, boolean privacy, boolean inOut, String description, Date startDate, Date endDate, District place, Collection<Notification> notificationCollection, Collection<PeopleInvited> peopleInvitedCollection) {
        String query = "UPDATE Event SET privacy = :privacy, inOut = :inOut, description = :description, date = :startDate, data_end = :endDate, place =  :place, notificationCollection = :notificationCollection, peopleInvitedCollection = :peopleInvitedCollection, WHERE Id_e = :eventId";
        em.createQuery(query)
                .setParameter("privacy", privacy)
                .setParameter("inOut", inOut)
                .setParameter("description", description)
                .setParameter("startDate", startDate)
                .setParameter("endDate", endDate)
                .setParameter("place", place)
                .setParameter("notificationCollection", notificationCollection)
                .setParameter("peopleInvitedCollection", peopleInvitedCollection)
                .setParameter("eventId", eventId)
                .executeUpdate();
    }

    public ArrayList<PeopleInvited> createPeopleInvited(ArrayList<String> invitedUsersNickname, Event event) {
        ArrayList<PeopleInvited> peopleInvitedCollection = new ArrayList<>();
        for (String userNickname : invitedUsersNickname) {
            PeopleInvited peopleInvited = new PeopleInvited(userNickname, event.getIde());
            peopleInvitedCollection.add(peopleInvited);
            em.persist(peopleInvited);
        }
        return peopleInvitedCollection;
    }

    public ArrayList<Notification> createNotificationCol(ArrayList<String> invitedUsersNickname, Event event) {
        ArrayList<Notification> NotificationCol = new ArrayList<>();
        for (String userNickname : invitedUsersNickname) {
            Notification notification = new Notification(userNickname, event.getIde());
            NotificationCol.add(notification);
            em.persist(notification);
        }
        return NotificationCol;
    }

}
